﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace remes.BLoc.UI
{
   /// <summary>
   /// Interaction logic for TranslationEditor.xaml
   /// </summary>
   public partial class TranslationEditor : Window
   {
      public TranslationEditor()
      {
         InitializeComponent();

         Columns = new List<GridColumn>();

         GroupingsList.Items.Filter = new Predicate<object>(GroupingsFilter);

         Columns.Add(new GridColumn("Stream name", "StreamName", true) { GroupBy = true });
         Columns.Add(new GridColumn("Key", "Key", false));
         Columns.Add(new GridColumn("Deleted", "IsDeleted", false) { FilterCheckBox = FilterDeletedCheckbox } );
         Columns.Add(new GridColumn("Readable", "IsReadable", false) { FilterCheckBox = FilterReadableCheckbox } );
         Columns.Add(new GridColumn("Modifiable", "IsModifiable", false) { FilterCheckBox = FilterModifiableCheckbox } );
         Columns.Add(new GridColumn("Category", "Category", true));
         Columns.Add(new GridColumn("Comments", "Comments", false));
         Columns.Add(new GridColumn("Orig. lang.", "OriginalLanguage", true));
         Columns.Add(new GridColumn("Orig. text", "OriginalText", false) { Width = 200 });
         Columns.Add(new GridColumn("State", null, true) { Template = FindResource("TextStateEditorTemplate") as DataTemplate });
         Columns.Add(new GridColumn("Text", null, false) { Width = 200, Template = FindResource("TextEditorTemplate") as DataTemplate });
         Columns.Add(new GridColumn("Lang.", "SelectedText.Language", false) { IsVisible = false });
         Columns.Add(new GridColumn("Translators comment", null, false) { Template = FindResource("TranslatorsCommentEditorTemplate") as DataTemplate });
      }

      private void Window_Loaded(object sender, RoutedEventArgs e)
      {
         UpdateGrouping();
         UpdateColumns();
      }

      private bool GroupingsFilter(object data)
      {
         var col = data as GridColumn;
         return col != null && col.CanGroup;
      }

      public TranslationSet TranslationSet
      {
         get { return (TranslationSet)GetValue(TranslationSetProperty); }
         set { SetValue(TranslationSetProperty, value); }
      }

      // Using a DependencyProperty as the backing store for TranslationSet.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty TranslationSetProperty =
          DependencyProperty.Register("TranslationSet", typeof(TranslationSet), typeof(TranslationEditor), new UIPropertyMetadata(null, OnTranslationSet_Changed));

      private static void OnTranslationSet_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
         (d as TranslationEditor).OnTranslationSet_Changed(e);
      }

      private void OnTranslationSet_Changed(DependencyPropertyChangedEventArgs e)
      {
         var oldSet = e.OldValue as TranslationSet;
         var newSet = e.NewValue as TranslationSet;

         if (oldSet != null)
         {
            oldSet.SelectedLang = null;
         }

         if (newSet != null)
         {
            if (newSet.TargetLanguages.Count > 0)
            {
               newSet.SelectedLang = newSet.TargetLanguages[0];
            }
         }
      }

      private void SaveCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
      {
         e.Handled = true;
         e.CanExecute = TranslationSet != null;
      }

      private void SaveCommand_Executed(object sender, ExecutedRoutedEventArgs e)
      {
         e.Handled = true;
         if (TranslationSet != null)
         {
            try
            {
               TranslationSet.Save();
            }
            catch (Exception ex)
            {
               MessageBox.Show(ex.Message);
            }
         }
      }

      private CollectionViewSource GetEntriesView()
      {
         return FindResource("EntriesView") as CollectionViewSource;
      }

      private void RefreshView()
      {
         var view = GetEntriesView();
         if (view != null && view.View != null)
         {
            view.View.Refresh();
         }
      }

      private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
      {
         var entry = e.Item as TranslationEntry;
         e.Accepted = entry != null 
            && (!FilterDeletedCheckbox.IsChecked.HasValue || FilterDeletedCheckbox.IsChecked.Value == entry.IsDeleted)
            && (!FilterReadableCheckbox.IsChecked.HasValue || FilterReadableCheckbox.IsChecked.Value == entry.IsReadable)
            && (!FilterModifiableCheckbox.IsChecked.HasValue || FilterModifiableCheckbox.IsChecked.Value == entry.IsModifiable)
            && (!FilterEmptyTextCheckbox.IsChecked.HasValue || FilterEmptyTextCheckbox.IsChecked.Value == entry.IsTextEmpty)
            && (!FilterNumberTextCheckbox.IsChecked.HasValue || FilterNumberTextCheckbox.IsChecked.Value == entry.IsTextNumber);
         if(e.Accepted)
         {
            var selectedText = entry.SelectedText;
            e.Accepted = selectedText == null
               || ((FilterStateNewTextCheckbox.IsChecked.Value && (selectedText.State == TranslationTextState.New))
                || (FilterStateOrigTextChangedTextCheckbox.IsChecked.Value && (selectedText.State == TranslationTextState.OriginalTextChanged))
                || (FilterStateAutoTranslatedTextCheckbox.IsChecked.Value && (selectedText.State == TranslationTextState.AutoTranslated))
                || (FilterStateTranslatedTextCheckbox.IsChecked.Value && (selectedText.State == TranslationTextState.Translated))
                || (FilterStateNoTranslationNeededTextCheckbox.IsChecked.Value && (selectedText.State == TranslationTextState.NoTranslationNeeded)));
         }
      }

      private void FilterCheckbox_Click(object sender, RoutedEventArgs e)
      {
         UpdateColumns();
         RefreshView();
      }

      private void TargetLanguageComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
      {
         RefreshView();
      }

      private void FilterShowAllButton_Click(object sender, RoutedEventArgs e)
      {
         FilterDeletedCheckbox.IsChecked = null;
         FilterReadableCheckbox.IsChecked = null;
         FilterModifiableCheckbox.IsChecked = null;
         FilterEmptyTextCheckbox.IsChecked = null;
         FilterNumberTextCheckbox.IsChecked = null;

         FilterStateNewTextCheckbox.IsChecked = true;
         FilterStateOrigTextChangedTextCheckbox.IsChecked = true;
         FilterStateAutoTranslatedTextCheckbox.IsChecked = true;
         FilterStateTranslatedTextCheckbox.IsChecked = true;
         FilterStateNoTranslationNeededTextCheckbox.IsChecked = true;
         
         UpdateColumns();
         RefreshView();
      }

      private void FilterShowDefaultButton_Click(object sender, RoutedEventArgs e)
      {
         FilterDeletedCheckbox.IsChecked = false;
         FilterReadableCheckbox.IsChecked = true;
         FilterModifiableCheckbox.IsChecked = true;
         FilterEmptyTextCheckbox.IsChecked = false;
         FilterNumberTextCheckbox.IsChecked = false;

         FilterStateNewTextCheckbox.IsChecked = true;
         FilterStateOrigTextChangedTextCheckbox.IsChecked = true;
         FilterStateAutoTranslatedTextCheckbox.IsChecked = true;
         FilterStateTranslatedTextCheckbox.IsChecked = false;
         FilterStateNoTranslationNeededTextCheckbox.IsChecked = false;

         UpdateColumns();
         RefreshView();
      }

      public List<GridColumn> Columns { get; private set; }

      private void UpdateColumns()
      {
         var view = new GridView();

         foreach (var col in Columns)
         {
            if (col.IsVisible && !col.GroupBy && (col.FilterCheckBox == null || !col.FilterCheckBox.IsChecked.HasValue))
            {
               var gvc = new GridViewColumn()
                  {
                     Header = col.Header,
                     Width = col.Width
                  };
               if (col.Template != null)
               {
                  gvc.CellTemplate = col.Template;
               }
               else
               {
                  gvc.DisplayMemberBinding = new Binding(col.PropertyName);
               }
               view.Columns.Add(gvc);
            }
         }

         EntriesList.View = view;
      }

      private void GroupingCheckBox_Changed(object sender, RoutedEventArgs e)
      {
         UpdateGrouping();
         UpdateColumns();
      }

      private void UpdateGrouping()
      {
         var view = GetEntriesView();
         if (view != null)
         {
            foreach (var col in Columns)
            {
               if (col.CanGroup)
               {
                  int idx = -1;
                  for (int n = 0; n < view.View.GroupDescriptions.Count; ++n)
                  {
                     var groupProp = view.View.GroupDescriptions[n] as PropertyGroupDescription;
                     if (groupProp != null && String.CompareOrdinal(groupProp.PropertyName, col.PropertyName) == 0)
                     {
                        idx = n;
                        break;
                     }
                  }
                  if (col.GroupBy && idx < 0)
                  {
                     view.View.GroupDescriptions.Add(new PropertyGroupDescription(col.PropertyName));
                  }
                  else if (!col.GroupBy && idx >= 0)
                  {
                     view.View.GroupDescriptions.RemoveAt(idx);
                  }
               }
            }
         }
      }

      private void AddTargetLanguageButton_Click(object sender, RoutedEventArgs e)
      {
         var dlg = new SelectCultureInfoDialog();
         dlg.Owner = this;
         dlg.ExclusiveLanguages = TranslationSet.TargetLanguages;
         var result = dlg.ShowDialog();
         if (result.HasValue && result.Value && dlg.SelectedLanguage != null)
         {
            TranslationSet.AddTargetLanguage(dlg.SelectedLanguage);
            TranslationSet.SelectedLang = dlg.SelectedLanguage;
         }
      }

      private void RemoveTargetLanguageButton_Click(object sender, RoutedEventArgs e)
      {
         if (MessageBox.Show(this, 
            "Are you sure to remove the current target language?\n\nAll Translations in this language will be deleted!", 
            "Remove target Language", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
         {
            TranslationSet.RemoveTargetLanguage(TranslationSet.SelectedLang);
            if (TranslationSet.TargetLanguages.Count > 0)
            {
               TranslationSet.SelectedLang = TranslationSet.TargetLanguages[0];
            }
         }
      }
   }

   public class GridColumn
   {
      public GridColumn(string header, string propertyName, bool canGroup)
      {
         Header = header;
         PropertyName = propertyName;
         CanGroup = canGroup;
         GroupBy = false;
         IsVisible = true;
         Width = Double.NaN;
         Template = null;
         FilterCheckBox = null;
      }

      public string Header { get; private set; }

      public string PropertyName { get; private set; }

      public bool CanGroup { get; private set; }

      public bool CanFilter { get; private set; }

      public bool GroupBy { get; set; }

      public bool IsVisible { get; set; }

      public double Width { get; set; }

      public DataTemplate Template { get; internal set; }

      public CheckBox FilterCheckBox { get; internal set; }
   }
}
